﻿using _80X_CG_Frame.Interfaces;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using _80X_CG_Frame.Workers;

namespace _80X_CG_Frame.Objects
{
    /// <summary>
    /// 激光焊接机接口实现
    /// </summary>
    public class LaserEngine : AsyncClient, ILaserEngine
    {
        static int max_fail = 5;//超x次失败重连
        int fail_count;
        int maxBufferSize = 4096;
        //static string params_pattern = @"^@(?:(?:""(?<key>.*?)"":""(?<value>.*?)""),?)*~$";
        //   @"key1":"value1","key2":"value2"~
        //static string msg_pattern = @"^@(?<params>.*?)~$";
        static string msg_pattern = @"^.*?,(?<jsons>.*)";
        static string json_pattern = @",?(?<json>{.*?}),?";
        static string param_pattern = @"(?:""(?<key>.*?)"":""(?<value>.*?)""),?";
        static string 螺母焊接参数查询命令 = "A1,2,nut2,nut3";
        static string 屏蔽片焊接参数查询命令 = "A1,1,X1";
        //Regex params_regex = new Regex(params_pattern, RegexOptions.IgnoreCase);
        static Regex msg_regex = new Regex(msg_pattern, RegexOptions.IgnoreCase);
        static Regex json_regex = new Regex(json_pattern, RegexOptions.IgnoreCase);
        static Regex param_regex = new Regex(param_pattern, RegexOptions.IgnoreCase);

        public LaserEngine()
        {
            fail_count = 0;
        }

        private bool Transmit(string msg, ref string result)
        {
            //string msg = "";
            byte[] byteSend = new byte[maxBufferSize];
            byte[] byteReceive = new byte[maxBufferSize];

            lock (client)
            {
                try
                {
                    if (ns != null && IsConnect)
                    {
                        byteSend = Encoding.ASCII.GetBytes(msg);

                        if (ns.CanWrite)
                            ns.Write(byteSend, 0, byteSend.Length);
                        else
                            DisConnect();
                        //ns.Flush();

                        if (ns.CanRead)
                        {

                            int len = ns.Read(byteReceive, 0, maxBufferSize);

                            if (len > 0)
                            {
                                //result = ByteArrayToStr(byteReceive, len);
                                result = Encoding.ASCII.GetString(byteReceive, 0, len);

                                return true;
                            //Console.Write("从机器人接收:" + result);
                            }
                            else
                            {
                                AutoDisConnect();
                            }

                        }
                        else
                        {
                            DisConnect();
                        }
                    }
                    else
                    {
                        DisConnect();
                    }
                }
                catch (Exception ex)
                {
                    AutoDisConnect();
                    Console.WriteLine(ex.ToString());
                }

            }
            return false;
        }
        /// <summary>
        /// 保留小数点后两位
        /// </summary>
        /// <param name="result"></param>
        /// <param name="retry"></param>
        /// <returns></returns>
        public bool 获取螺母焊接数据(out List<JObject> result, int retry = 5)
        {
            result = new List<JObject>();
            string recv = "";
            for(int i = 0;i < retry;i++)
            {
                if(Transmit(螺母焊接参数查询命令, ref recv))
                {
                    var temp_list = GetLaserConfigs(recv);
                    if(temp_list.Count >= 2)
                    {
                        var nut2 = new JObject();
                        var raw_nut2 = temp_list[0];
                        nut2["station"] = "nut2";
                        nut2["machine_module"] = GLOBAL.config.Get("螺母焊接机台编号");
                        nut2["work_time"] = DateTime.Now.ToString("yyyyMMddHHmmss");
                        nut2["power"] = Convert.ToDouble((string)raw_nut2["power"]).ToString("F2");
                        nut2["speed"] = Convert.ToDouble((string)raw_nut2["linear_speed"]).ToString("F2");
                        nut2["parameters_waveform"] = "0.00";
                        nut2["frequency"] = Convert.ToDouble((string)raw_nut2["frequency"]).ToString("F2");
                        nut2["energy"] = "0.00";
                        nut2["peak_power"] = "0.00";
                        nut2["pulse_width"] = "0.00";
                        var nut3 = new JObject();
                        var raw_nut3 = temp_list[1];
                        nut3["station"] = "nut3";
                        nut3["machine_module"] = GLOBAL.config.Get("螺母焊接机台编号");
                        nut3["work_time"] = DateTime.Now.ToString("yyyyMMddHHmmss");
                        nut3["power"] = Convert.ToDouble((string)raw_nut3["power"]).ToString("F2");
                        nut3["speed"] = Convert.ToDouble((string)raw_nut3["linear_speed"]).ToString("F2");
                        nut3["parameters_waveform"] = "0.00";
                        nut3["frequency"] = Convert.ToDouble((string)raw_nut3["frequency"]).ToString("F2");
                        nut3["energy"] = "0.00";
                        nut3["peak_power"] = "0.00";
                        nut3["pulse_width"] = "0.00";
                        result = new List<JObject> { nut2, nut3};
                        return true;
                    }
                    break;
                }
            }
            return false;
        }
        public bool 获取屏蔽片焊接数据(out List<JObject> result, int retry = 5)
        {
            result = new List<JObject>();
            string recv = "";
            for (int i = 0; i < retry; i++)
            {
                if (Transmit(屏蔽片焊接参数查询命令, ref recv))
                {
                    var temp_list = GetLaserConfigs(recv);
                    if (temp_list.Count >= 1)
                    {
                        var shield_piece = new JObject();
                        var raw_shield = temp_list[0];
                        shield_piece["station"] = "shield_piece";
                        shield_piece["machine_module"] = GLOBAL.config.Get("屏蔽片焊接机台编号");
                        shield_piece["work_time"] = DateTime.Now.ToString("yyyyMMddHHmmss");
                        shield_piece["power"] = Convert.ToDouble((string)raw_shield["power"]).ToString("F2");
                        shield_piece["speed"] = Convert.ToDouble((string)raw_shield["linear_speed"]).ToString("F2");
                        shield_piece["parameters_waveform"] = "0.00";
                        shield_piece["frequency"] = Convert.ToDouble((string)raw_shield["frequency"]).ToString("F2");
                        shield_piece["energy"] = "0.00";
                        shield_piece["peak_power"] = "0.00";
                        shield_piece["pulse_width"] = "0.00";
                        result = new List<JObject> { shield_piece };
                        return true;
                    }
                    break;
                }
            }
            return false;
        }
        //public static Dictionary<string, string> GetLaserConfigs(string str)
        //{
        //    Dictionary<string, string> params_dic = new Dictionary<string, string>();

        //    Match msg_match = msg_regex.Match(str);
        //    if(msg_match.Success)
        //    {
        //        string params_str = msg_match.Groups["params"].Value;
        //        MatchCollection mc = param_regex.Matches(params_str);
        //        foreach(Match m in mc)
        //        {
        //            params_dic[m.Groups["key"].Value] = m.Groups["value"].Value;
        //        }
        //    }
        //    /*
        //    MatchCollection mc = params_regex.Matches(str);
        //    foreach (Match m in mc)
        //    {
        //        params_dic[m.Groups["key"].Value] = m.Groups["value"].Value;
        //    }
        //    */

        //    return params_dic;
        //}
        public static List<JObject> GetLaserConfigs(string str)
        {

            List<JObject> result = new List<JObject>();
            Match msg_match = msg_regex.Match(str);
            if (msg_match.Success)
            {
                //string json_str = msg_match.Groups["params"].Value;
                string jsons_str = msg_match.Groups["jsons"].Value;
                MatchCollection json_matchs = json_regex.Matches(jsons_str);
                foreach(Match m in json_matchs)
                {

                    //Match json_match = param_regex.Match(json_pattern);
                    //Console.WriteLine("json解析" + m.Groups["json"].Value);

                    result.Add(JObject.Parse(m.Groups["json"].Value));
                }
            }
            //Console.WriteLine("激光机台原消息" + str);
            //Console.WriteLine("激光机台json解析" + result.ToString());
            return result;
        }
        /// <summary>
        /// 超时自动断连
        /// </summary>
        private void AutoDisConnect()
        {
            fail_count++;
            if (fail_count >= max_fail)
            {
                fail_count = 0;
                DisConnect();
            }
        }
    }
}
